/*
 * TLD7002_HAL.c
 *
 *  Created on: 2023��5��2��
 *      Author: CaiYingming
 */

/*******************************************************************************
 includes
 *******************************************************************************/
#include "TLD7002_HAL.h"

/*******************************************************************************
 defines
 *******************************************************************************/
#if (INST_LPUART_TLD7002==0U)
	#define LPUART_TLD7002 LPUART0
#elif (INST_LPUART_TLD7002==1U)
	#define LPUART_TLD7002 LPUART1
#else
	#define LPUART_TLD7002 LPUART2
#endif

/*******************************************************************************
 global variables
 *******************************************************************************/
TLD7002_NetworkInstance_t TLD7002Network =
{
	0,						/* reset master rolling counter */
	{ 0 },					/* reset the slave rolling counters */
	sendTLD7002Message,		/* microcontroller specific writing UART over CAN function */
	readReceivedTLD7002Answer,	/* microcontroller specific reading UART over CAN function */
	emptyingReceiveBuffer,	/* microcontroller specific emptying the UART receive buffer function */
	generateStartSyncBreak,	/* microcontroller specific function to start sync break generation */
	generateStopSyncBreak,	/* microcontroller specific function to stop sync break generation */
};

/* WRITE_REG and READ_REG messages use max bytes which number is (5+64)+2=71 */
uint8 ReadBuffer_TLD7002[71] = {0};

/*******************************************************************************
 local variables
 *******************************************************************************/
uint8 size_rcv_data = 0;
status_t status;
/*******************************************************************************
 global functions declare
 *******************************************************************************/

/*******************************************************************************
 local functions declare
 *******************************************************************************/

/*******************************************************************************
 global functions
 *******************************************************************************/

/*******************************************************************************
 local functions
 *******************************************************************************/

/*********************************************************************************************************
** Function name:       readReceivedTLD7002Answer
** Descriptions:        The microcontroller-specific UART transmit function
** input parameters:
** uint8 *txBuffer:     the uint8 type transmit buffer array, containing the generated HSLI control frame
** uint32 len_write:    the length of data to transmit
** output parameters:   N/A
** Returned value:      N/A
*********************************************************************************************************/
void sendTLD7002Message(uint8 *txBuffer, uint32 len_write)
{
	/* Enable receiver */
	LPUART_DRV_ReceiveData(INST_LPUART_TLD7002, ReadBuffer_TLD7002, 1U);
	/* The function does not return until the transmit is complete or timeout(2ms) occured */
	LPUART_DRV_SendDataBlocking(INST_LPUART_TLD7002, txBuffer, len_write, 2);
}

/*********************************************************************************************************
** Function name:       readReceivedTLD7002Answer
** Descriptions:        the microcontroller-specific UART receive function
** input parameters:
** uint8* read_dest:    the uint8 type receive buffer array
** uint32 len_read:     the length of data to be received
** output parameters:   N/A
** Returned value:      return true or false, depending on whether the data was read successfully.
*********************************************************************************************************/
boolean readReceivedTLD7002Answer(uint8* read_dest, uint32 len_read)
{
	boolean copy_successful = FALSE;				/*< copy initially not ok */

    /* wait for IDLE */
    while(!(LPUART_GetStatusFlag(LPUART_TLD7002, LPUART_IDLE_LINE_DETECT)));

	/* ReadBuffer_TLD7002 contains sent and received data. Therefore calculate
	 * length of written data by subtracting the expected length to read
	 * (input parameter) from size of received data.
	 * This should be only calculated, if the length of received data is bigger
	 * than the length of expected answer */
	uint32 len_write = (size_rcv_data > len_read) ? size_rcv_data - len_read : 0;

	/*< if the the length of written data is not 0 (seems to be a valid answer)*/
	if(len_write != 0)
	{
		/*< Go through the individual elements of the buffer */
		for(uint32 index=0; index < (len_write + len_read); index++)
		{
			/*< the first elements include the data written to TLD7002. The elements after them include the response read from TLD7002. */
			if(index >= len_write)
			{
				/*< copy data */
				*read_dest = ReadBuffer_TLD7002[index];
				/*< increase the address of the buffer array */
				read_dest++;
				/*< copy data seems to be copy_successful, if this if is called minimum one time */
				copy_successful = TRUE;
			}
		}
	}

#ifndef	USE_PRINTF
	/* debug, if baudrate < 500, add timeout */
	LPUART_DRV_SendDataBlocking(INST_LPUART_OPENSDA, ReadBuffer_TLD7002, size_rcv_data, 2);
#endif

	/* reset num of receive buffer */
	size_rcv_data = 0;

	/* disable receiver */
	LPUART_DRV_AbortReceivingData(INST_LPUART_TLD7002);

	return copy_successful;
}

/*********************************************************************************************************
** Function name:       emptyingReceiveBuffer
** Descriptions:        the receiver buffer has to be flashed for broadcast messages, by calling this function
** input parameters:    N/A
** output parameters:   N/A
** Returned value:      N/A
*********************************************************************************************************/
void emptyingReceiveBuffer(void)
{
	/*
	 * functions:
	 * emptying receive buffer by reading out and reset of index
	 *
	 * */

    /* wait for IDLE */
    while(!(LPUART_GetStatusFlag(LPUART_TLD7002, LPUART_IDLE_LINE_DETECT)));

#ifndef	USE_PRINTF
    /* debug, if baudrate < 500, add timeout*/
	LPUART_DRV_SendDataBlocking(INST_LPUART_OPENSDA, ReadBuffer_TLD7002, size_rcv_data, 2);
#endif

	/* reset num of receive buffer */
	size_rcv_data = 0;

	/* disable receiver */
	LPUART_DRV_AbortReceivingData(INST_LPUART_TLD7002);


}

/*********************************************************************************************************
** Function name:       generateStartSyncBreak
** Descriptions:        a high-to-low transition on the UART TX pin, creating a start sync break
** input parameters:    N/A
** output parameters:   N/A
** Returned value:      N/A
*********************************************************************************************************/
void generateStartSyncBreak(void)
{
	/* Reconfigure UART TX pin to GPIO pin and set Tx Pin to Low */
	PINS_DRV_SetMuxModeSel(PORTC, 7u, PORT_MUX_AS_GPIO);
	PINS_DRV_SetPinDirection(PTC, 7u, GPIO_OUTPUT_DIRECTION);
	PINS_DRV_WritePin(PTC, 7u, LOW);
	/* Possible strategy on microcontroller:
	 * 1. Set pin to output mode (e.g. at alternative pin function for GPIO in pushPull configuration)
	 * 2. Set pin pad driver to suitable strength for GPIO
	 * 3. Set pin output state to low
	 */
}

/*********************************************************************************************************
** Function name:       generateStopSyncBreak
** Descriptions:        a low-to-high transition on the UART TX pin, creating a stop sync break
** input parameters:    N/A
** output parameters:   N/A
** Returned value:      N/A
*********************************************************************************************************/
void generateStopSyncBreak(void)
{
	/* Reconfigure GPIO pin to UART TX pin and set Tx Pin to High */
	PINS_DRV_SetMuxModeSel(PORTC, 7u, PORT_MUX_ALT2);
	PINS_DRV_WritePin(PTC, 7u, HIGH);
	/* Possible strategy on microcontroller:
	 * 1. Set Pin output state to high
	 * 2. Set pin to UART mode (e.g. at alternative pin function for UART in push pull configuration)
	 * 3. Set pin pad driver to suitable strength for UART
	 */
}

/*********************************************************************************************************
** Function name:       Lpuart1RxCallback
** Descriptions:        N/A
** input parameters:    N/A
** output parameters:   N/A
** Returned value:      N/A
*********************************************************************************************************/
void Lpuart_tld7002_RxCallback(void *driverState, uart_event_t event, void *userData)
{
    /* Unused parameters */
    (void)driverState;
    (void)userData;

    /* Check the event type */
    if (event == UART_EVENT_RX_FULL)
    {
        /* Update the buffer index and the rx buffer */
    	size_rcv_data++;
    	LPUART_DRV_SetRxBuffer(INST_LPUART_TLD7002, &ReadBuffer_TLD7002[size_rcv_data], 1U);

    }
}

/*********************************************************************************************************
** Function name:       generateSyncBreak
** Descriptions:        send break which length is 13bit
** input parameters:    N/A
** output parameters:   N/A
** Returned value:      N/A
*********************************************************************************************************/
void generateSyncBreak()
{
	/* TDRE : Transmit Data Register Empty Flag
	 * 0b - Transmit data buffer full.
	 * 1b - Transmit data buffer empty
	 * */
	while ((LPUART0->STAT & LPUART_STAT_TDRE_MASK) == 0);

	/* BRK13 : Break Character Generation Length
	 * This bit should only be changed when the transmitter is disabled��
	 * 0b - Break character is transmitted with length of 9 to 13 bit times
	 * 1b - Break character is transmitted with length of 12 to 15 bit times.
	 * */
	//LPUART0->CTRL &= ~LPUART_CTRL_TE_MASK;	/* TE has been clear to 0 in SDK */
	LPUART0->STAT |= LPUART_STAT_BRK13_MASK;
	LPUART0->CTRL |= LPUART_CTRL_TE_MASK;

	/* SBK : Send Break
	 * Writing a 1 and then a 0 to SBK queues a break character in the transmit data stream
	 * 0b - Normal transmitter operation.
	 * 1b - Queue break character(s) to be sent.
	 * */
	LPUART0->CTRL |= LPUART_CTRL_SBK_MASK;
    LPUART0->CTRL &= ~LPUART_CTRL_SBK_MASK;

    /* TC : Transmission Complete Flag
     * 0b - Transmitter active (sending data, a preamble, or a break).
	 * 1b - Transmitter idle (transmission activity complete).
     * */
    while ((LPUART0->STAT & LPUART_STAT_TC_MASK) == 0);
    /* generate 26us "1" after 26us "0"(break)*/
    //us_Delay(26);
    LPUART0->CTRL &= ~LPUART_CTRL_TE_MASK;
}




/*********************************************************************************************************
  End Of File
*********************************************************************************************************/
